//2.分析，主要负责网页内容抽取、分词，构建临时索引，计算 PageRank 值这几部分工作。
package main

import (
	"SearchEngine/analysis/extractInformation"
	"SearchEngine/analysis/splitWords"
	"bufio"
	"fmt"
	"os"
	"strconv"
	"sync"
)

var (
	wordNumber int64            = 0                      // 统计已爬取的单词总数,作为单词编号
	mutex      sync.Mutex                                // wordNumber变量的锁
	docID      int64                                     // 网页编号
	words      []*word                                   // 存储全部单词信息
	wordsHash  map[string]int64 = make(map[string]int64) //维护单词编号hash表
)

//一个单词的全部信息
type word struct {
	text   string //单词文本
	termID int64  //单词编号
	docID  int64  //所属网页编号
}

//获得单词唯一编号
func getWordNumber() int64 {
	mutex.Lock()
	defer mutex.Unlock()
	wordNumber++
	return wordNumber
}

//存储全部单词信息
func getWords(wordsText []string) {
	//1.网页编号
	docID = <-extractInformation.OneWebIndex
	//2.单词编号
	for _, wordText := range wordsText {
		termID, ok := wordsHash[wordText] //已存在则直接取得原ID
		if !ok {
			termID = getWordNumber()
			wordsHash[wordText] = termID //不存在则分配新ID，并存入hash表
			temp := &word{text: wordText, termID: termID, docID: docID}
			words = append(words, temp)
		}
	}
	fmt.Println("存储全部单词信息完成")
}

// 创建单词编号，保存到文件（term_id.bin）
func savetermIDTofile(filmName string, words []*word) {
	f, err := os.OpenFile(filmName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
	if err != nil {
		fmt.Println("SavetermIDTofile:", err)
		return
	}
	defer f.Close()
	//使用 bufio.NewWriter 写入文件
	w := bufio.NewWriter(f)
	fmt.Println("开始创建单词编号,并保存到文件")
	for _, word := range words {
		//1.先写入网页编号
		indexString := strconv.Itoa(int(word.termID))
		w.WriteString(indexString + ":")
		//2.再写入单词
		w.WriteString(word.text + "\n")
	}
	w.Flush()
}

// 创建单词临时索引，保存到文件（tmp_Index.bin）
func saveTmpIndexTofile(filmName string, words []*word) {
	f, err := os.OpenFile(filmName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
	if err != nil {
		fmt.Println("SavetermIDTofile:", err)
		return
	}
	defer f.Close()
	//使用 bufio.NewWriter 写入文件
	w := bufio.NewWriter(f)
	fmt.Println("开始创建单词临时索引,并保存到文件")
	for _, word := range words {
		//1.先写入单词编号
		termIDString := strconv.Itoa(int(word.termID))
		w.WriteString(termIDString + "\t")
		//2.再写入网页编号
		docIDString := strconv.Itoa(int(word.docID))
		w.WriteString(docIDString + "\r\n")
	}
	w.Flush()
}

func main() {
	//1.读取一个单独网页源代码
	//2.抽取网页文本信息
	go extractInformation.GetExtractResult()
	//3.经过上面的处理之后，我们就从网页中抽取出了我们关心的文本信息。接下来，我们要对文本信息进行分词，并且创建临时索引
	wordsText := splitWords.GetSplitWords()
	//4.利用分词生成全部单词信息
	getWords(wordsText)
	//5.创建单词编号，保存到文件（term_id.bin）
	filmName := "/home/fcou/go/src/SearchEngine/analysis/termId/term_id.bin"
	savetermIDTofile(filmName, words)
	//6.创建临时索引，保存到文件（tmp_index.bin）
	filmName = "/home/fcou/go/src/SearchEngine/analysis/tmpIndex/tmp_Index.bin"
	saveTmpIndexTofile(filmName, words)
}
